package com.neouton.crm.pm.service.impl;

import cn.afterturn.easypoi.excel.entity.TemplateExportParams;
import cn.hutool.core.collection.CollUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.alibaba.excel.write.style.column.SimpleColumnWidthStyleStrategy;
import com.alibaba.excel.write.style.row.SimpleRowHeightStyleStrategy;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO;
import com.neouton.common.entity.ActivitiVO;
import com.neouton.common.entity.FeeMainVO;
import com.neouton.common.util.*;
import com.neouton.crm.approval.entity.ApprovalVO;
import com.neouton.crm.approval.service.IApprovalService;
import com.neouton.crm.dictionary.entity.DictionaryLookupItemVO;
import com.neouton.crm.dictionary.service.IDictionaryService;
import com.neouton.crm.entity.DynamicExcelData;
import com.neouton.crm.entity.SysUserEntity;
import com.neouton.crm.op.entity.SalesOpportunityVO;
import com.neouton.crm.op.mapper.SalesOpportunityMapper;
import com.neouton.crm.paymentPlan.entity.PaymentPlan;
import com.neouton.crm.paymentPlan.mapper.PaymentPlanMapper;
import com.neouton.crm.pm.entity.*;
import com.neouton.crm.pm.mapper.PurchaseOrdeMapper;
import com.neouton.crm.pm.mapper.SalesProjectManageMapper;
import com.neouton.crm.pm.service.IPurchaseOrdeService;
import com.neouton.crm.screen.Hander.MapResultHandler;
import com.neouton.crm.transpondEmail.service.TranspondEmailService;
import com.neouton.feginClient.FeginService;
import com.neouton.feginClient.ReimburseService;
import com.neouton.feginClient.WorkFlowFeginService;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.concurrent.CompletableFuture;

import static com.neouton.common.util.EasyExcelUtils.dynamicExport;
import static com.neouton.common.util.EasyExcelUtils.getDataList;

/**
 * 采购相关Service
 * @Author libingkun
 * @Date 2022年11月30日
 * @Version 1.0
 *          初始化迁移
 */
@Service
public class PurchaseOrdeServiceImpl implements IPurchaseOrdeService {

    @Resource
    private WorkFlowFeginService workFlowFeginService;

    @Resource
    private SalesProjectManageMapper projectManageMapper;

    @Resource
    private PurchaseOrdeMapper purchaseOrdeMapper;

    @Resource
    private PaymentPlanMapper paymentPlanMapper;

    @Resource
    private IDictionaryService dictionaryService;

    @Resource
    private IApprovalService approvalService;

    @Resource
    private TranspondEmailService transpondEmailService;

    @Resource
    FeginService feginService;

    @Value("${webSit.web}")
    private String webSitUrl;

    /**
     * 保存采购信息
     * @param purchaseOrder
     * @return
     */
    @Transactional
    public Integer saveOrUpdatePurchaseOrder(PurchaseOrderVO purchaseOrder,String token){
        //1.发起工作流
        //获取审批人
        SysUserEntity user = dictionaryService.queryMenuUserIdsByCode("commercialSpecialist").get(0);
        //获取人员信息
        Integer businessId = this.startPurchaseOrdeApproval(user);
        //2.记录本地审批数据
        //生成审批主表信息，日志信息
        ApprovalVO approval = approvalService.initApprovalAndLog(businessId, 23, purchaseOrder.getAskReason(),
                "", -1,"");
        //之后更新/保存
        purchaseOrder.setApprovalId(approval.getApprovalId());

        if( null == purchaseOrder.getPurchaseId() ){
            //生成采购单号
            purchaseOrder.setPurchaseNo(purchaseOrder.getPurchaseNo().replace("...",this.getPurchaseOrdeMaxNumByDate()));
            //保存主表信息
            purchaseOrdeMapper.savePurchaseOrder(purchaseOrder);
            Integer purchaseOrdeId=  purchaseOrder.getPurchaseId();

            PurchaseOrderVO purchaseOrderVO = this.getPurchaseOrdeInfoById(purchaseOrdeId);

            List<PaymentPlan> paymentPlanList = new ArrayList<>();
            for (PaymentPlan paymentPlan : purchaseOrder.getPaymentPlans()) {
                if(purchaseOrder.getProjectManageId() != null) {
                    paymentPlan.setProjectManageId(purchaseOrder.getProjectManageId());
                    paymentPlan.setPurchaseCategories(1);
                }else {
                    paymentPlan.setOpportunityId(purchaseOrder.getOpportunityId());
                    paymentPlan.setPurchaseCategories(0);
                }

                paymentPlan.setPurchaseTopic(purchaseOrder.getPurchaseTopic());
                paymentPlan.setPurchaseId(purchaseOrder.getPurchaseId());
                paymentPlan.setApprovalId(approval.getApprovalId());
                paymentPlan.setPurchaseNo(purchaseOrderVO.getPurchaseNo());
                paymentPlan.getSupplier().setSupplierId(purchaseOrder.getSupplier().getSupplierId());
                paymentPlanList.add(paymentPlan);
            }
            paymentPlanMapper.savePayPlan(paymentPlanList);

        }else {
            //1.备份主表信息
            //2.备份从表信息
            purchaseOrdeMapper.backUpPurchaseOrder(purchaseOrder);
            paymentPlanMapper.backUpPayPlan(purchaseOrder.getPurchaseId(),AuthUtils.getUserId());
            purchaseOrdeMapper.updatePurchaseOrder(purchaseOrder);
            List<PaymentPlan> paymentPlanList = new ArrayList<>();
            for (PaymentPlan paymentPlan : purchaseOrder.getPaymentPlans()) {
                paymentPlan.setPurchaseId(purchaseOrder.getPurchaseId());
                paymentPlan.setPurchaseNo(purchaseOrder.getPurchaseNo());
                if(purchaseOrder.getProjectManageId() != null) {
                    paymentPlan.setProjectManageId(purchaseOrder.getProjectManageId());
                    paymentPlan.setPurchaseCategories(1);
                }else {
                    paymentPlan.setOpportunityId(purchaseOrder.getOpportunityId());
                    paymentPlan.setPurchaseCategories(0);
                }
                paymentPlan.setPlanPeriod(String.valueOf(Integer.parseInt(paymentPlan.getPlanPeriod()) -1));
                paymentPlan.setApprovalId(purchaseOrder.getApprovalId());
                paymentPlan.setPlanPeriod(String.valueOf(Integer.parseInt(paymentPlan.getPlanPeriod())+1));
                paymentPlanList.add(paymentPlan);
            }
            paymentPlanMapper.updatePayPlanByIds(purchaseOrder.getPaymentPlans(),purchaseOrder.getPurchaseId());
        }
        //保存从表信息
        purchaseOrdeMapper.savePurchaseOrderProduct(purchaseOrder.getPurchaseOrderProducts(),purchaseOrder.getPurchaseId());
        //保存抄送人
        transpondEmailService.insertTranspondEmailInfoByUser(purchaseOrder.getApprovalId(),purchaseOrder.getForwardUsers());
        if(AuthUtils.getUserAccount().equals(user.getAccount())){
            //跳过第一步审批
            this.approvePurchaseOrderInfo(purchaseOrder,token,true);
        }else {
            //发送审批邮件
            //发送邮件
            approvalService.updateNextApproverByApprovalId(user.getUserId(),approval.getApprovalId());
//            String titel = "【系统通知】采购信息 - 流程单审批通知";
//            String msg = "<div><p >" + "尊敬的" + user.getLoginName() + "：</p></div>" +
//                    "<div><p style='text-indent: 2em'>您好，您有一张新的采购信息审批需要处理：</p></div>"+
//                    "<div><p style='text-indent: 2em'>事项编号："+approval.getApprovalCode()+"</p></div>"+
//                    "<div><p style='text-indent: 2em'>申请人："+ AuthUtils.getUserName() +" / "+ AuthUtils.getUserAccount()+"</p></div>"+
//                    "<div><p style='text-indent: 2em'>申请原因："+ (StringUtils.isEmpty(purchaseOrder.getAskReason()) ? "无":purchaseOrder.getAskReason())+"</p></div>"+
//                    "<div><p style='text-indent: 2em'>申请时间："+ DateUtils.getCurrentTime() +"</p></div>"+
//                    "<div><p style='text-indent: 2em'>采购名称："+purchaseOrder.getPurchaseTopic()+"</p></div>"+
//                    "<div><p style='text-indent: 2em'>采购单号："+purchaseOrder.getPurchaseNo()+"</p></div>"+
//                    "<div><p style='text-indent: 2em'>付款期次：共"+purchaseOrder.getPaymentPlanPeriod()+"期</p></div>"+
//                    "<div><p style='text-indent: 2em'>系统审批路径：客户关系管理系统 - 待办事项 - 待办审批 " +
//                    "<a href='"+webSitUrl+"/?m=crm&p=crmtodoItems&me=todoApprovalPath'>进入</a></p></div>"+
//                    "<div><p style='text-indent: 2em'>谢谢！</p></div>"+
//                    "<div><p style='text-indent: 2em'>说明：该邮件为系统自动发送，请勿回复。</p></div>";
//            CompletableFuture.runAsync(() -> EmailUtils.sentMailByAddressee(user.getEmail(),null,titel,msg,token));
            //调用通知接口生成待办通知
            Integer userId = AuthUtils.getUserId();
            CompletableFuture.runAsync(() -> NoticUtils.pushNotic(approval.getApprovalId(), new Timestamp(System.currentTimeMillis()),
                    userId,0,23,user.getUserId(),token));
       }
        return purchaseOrder.getPurchaseId();
    }

    /**
     * 获取当日最大采购单号
     * @return
     */
    public String getPurchaseOrdeMaxNumByDate(){
        Integer num = purchaseOrdeMapper.getPurchaseOrdeMaxNumByDate();
        if(num<10)
            return "0"+num;
        else
            return num.toString();
    }

    /**
     * 更具项目ID获取所有采购信息
     */
    public List<PurchaseOrderVO> queryPurchaseOrdersByProjectId(Integer projectId){
        return purchaseOrdeMapper.queryPurchaseOrdersByProjectId(projectId);
    }

    /**
     * 更具机会ID查询采购信息
     */
    public List<PurchaseOrderVO> queryPurchaseOrdersByOpId(Integer opId){
        return purchaseOrdeMapper.queryPurchaseOrdersByOpId(opId);
    }

    /**
     * 更具采购单ID获取采购信息
     * @param purchaseOrdeId
     * @return
     */
    public PurchaseOrderVO getPurchaseOrdeInfoById(Integer purchaseOrdeId){
        PurchaseOrderVO purchaseOrde = purchaseOrdeMapper.getPurchaseOrdeInfoById(purchaseOrdeId);
        purchaseOrde.setForwardUsers(transpondEmailService.queryTranspondByApprovalId(purchaseOrde.getApproval().getApprovalId()));
        return purchaseOrde;
    }

    /**
     * 采购信息驳回审批
     * @param purchaseOrder
     * @return
     */
    @Transactional
    public Boolean rejectionPurchaseOrderInfo(PurchaseOrderVO purchaseOrder, String token){
        //获取工作流ID
        ApprovalVO approval = approvalService.queryApprovalByAppID(purchaseOrder.getApprovalId());

        ActivitiVO activitiVO = new ActivitiVO();
        activitiVO.setBusinessId(approval.getBusinessId());
        activitiVO.setAuthorization(AuthUtils.getUserAccount());
//        ResponseAPI<ActivitiVO> processNodeNameAndCode = workFlowFeginService.getProcessNodeNameAndCode(activitiVO);
        //删除流程实例
        workFlowFeginService.deleteInstance(activitiVO);
        //驳回
//        workFlowFeginService.rejectedByBusinessId(activitiVO);
        SysUserEntity user = null;
        Integer workState;
        String titel;
        String msg;
        Integer todoUser;
        SysUserEntity askUser = feginService.searchUserInfoById(approval.getCreator(),token).getResult();
        //当第一步为商务时，驳回至起点
//        if( "商务审批".equals(processNodeNameAndCode.getResult().getName()) ){
            user = askUser;
            workState = 1;
            titel= "【系统通知】采购信息 - 流程单审批驳回通知";
            msg = "<div><p >" + "尊敬的" + askUser.getLoginName() + "：</p></div>" +
                    "<div><p style='text-indent: 2em'>您好，您提交的采购信息审批已被驳回：</p></div>"+
                    "<div><p style='text-indent: 2em'>事项编号："+approval.getApprovalCode()+"</p></div>"+
                    "<div><p style='text-indent: 2em'>审批人："+askUser.getLoginName()+" / "+askUser.getAccount()+"</p></div>"+
                    "<div><p style='text-indent: 2em'>审批意见："+(StringUtils.isEmpty(purchaseOrder.getAppReason()) ? "无":purchaseOrder.getAppReason())+"</p></div>"+
                    "<div><p style='text-indent: 2em'>审批时间："+ DateUtils.getCurrentTime() +"</p></div>"+
                    "<div><p style='text-indent: 2em'>采购名称："+purchaseOrder.getPurchaseTopic()+"</p></div>"+
                    "<div><p style='text-indent: 2em'>采购单号："+purchaseOrder.getPurchaseNo()+"</p></div>"+
                    "<div><p style='text-indent: 2em'>付款期次：共"+purchaseOrder.getPaymentPlanPeriod()+"期</p></div>"+
                    "<div><p style='text-indent: 2em'>系统查看路径：客户关系管理系统 - 项目信息管理 - 项目信息 " +
                    "<a href='"+webSitUrl+"/?m=crm&p=projectmanage&me=projectmanageInfo'>进入</a></p></div>"+
                    "<div><p style='text-indent: 2em'>谢谢！</p></div>"+
                    "<div><p style='text-indent: 2em'>说明：该邮件为系统自动发送，请勿回复。</p></div>";
            approvalService.approvalRejection(null,purchaseOrder.getApprovalId());
            todoUser = 0;
//        }else {
//            //获取上一人
//            if("财务审批".equals(processNodeNameAndCode.getResult().getName())){
//                user = dictionaryService.queryMenuUserIdsByCode("commercialSpecialist").get(0);
//            }else if("售后审批".equals(processNodeNameAndCode.getResult().getName())){
//                user = dictionaryService.queryMenuUserIdsByCode("finance").get(0);
//            }else if("总经理审批".equals(processNodeNameAndCode.getResult().getName())){
//                user = dictionaryService.queryMenuUserIdsByCode("afterSales").get(0);
//            }else if("董事长审批".equals(processNodeNameAndCode.getResult().getName())){
//                user = dictionaryService.queryMenuUserIdsByCode("president").get(0);
//            }
//            workState = 0;
//            titel = "【系统通知】采购信息审批待处理通知";
//            msg =  initPurchaseOrdeEmailData(user.getLoginName(),"您有一张采购审批已被上级驳回需处理"
//                    ,approval.getApprovalCode(), askUser.getLoginName(),purchaseOrder.getPurchaseTopic(),purchaseOrder.getPurchaseNo(),
//                    purchaseOrder.getPaymentPlanPeriod());
//            todoUser = user.getUserId();
//            approvalService.updateNextApproverByApprovalId(user.getUserId(),purchaseOrder.getApprovalId());
//        }
        //记录日志
        approvalService.insertApprovalLog(approval.getApprovalId(),"驳回",
                "",purchaseOrder.getAppReason());
        SysUserEntity finalUser = user;
        CompletableFuture.runAsync(() -> EmailUtils.sentMailByAddressee(finalUser.getEmail(),null,titel,msg,token));
        Integer userId = AuthUtils.getUserId();
        CompletableFuture.runAsync(() -> NoticUtils.pushNotic(purchaseOrder.getApprovalId(),  approval.getCreateDataTime(),
                userId,workState,23,todoUser,token));
        return true;
    }

    /**
     * 采购信息通过审批
     * @param purchaseOrder
     * @return
     */
    @Transactional
    public Boolean approvePurchaseOrderInfo(PurchaseOrderVO purchaseOrder,String token,Boolean auto){
        //获取工作流ID
        ApprovalVO approval = approvalService.queryApprovalByAppID(purchaseOrder.getApprovalId());
        ActivitiVO activitiVO = new ActivitiVO();
        activitiVO.setBusinessId(approval.getBusinessId());
        activitiVO.setAuthorization(AuthUtils.getUserAccount());
        ResponseAPI<ActivitiVO> processNodeNameAndCode = workFlowFeginService.getProcessNodeNameAndCode(activitiVO);
        SysUserEntity user = null;
        Integer workState;
        String titel;
        String msg;
        Integer todoUser;
        String ccUser = null;
        //整体通过
        SysUserEntity askUser = feginService.searchUserInfoById(approval.getCreator(),token).getResult();
        //记录审批日志
        if(auto){
            approvalService.insertApprovalLog(approval.getApprovalId(),"通过",
                    "系统判定跳过",purchaseOrder.getAppReason());
        }else {
            //记录日志
            approvalService.insertApprovalLog(approval.getApprovalId(),"通过",
                    "",purchaseOrder.getAppReason());
        }
        if( "董事长审批".equals(processNodeNameAndCode.getResult().getName()) ){
            //审批通过
            workFlowFeginService.approvalProcessByBusinessId(activitiVO);
            user=askUser;
            workState = 1;
            todoUser = 0;
            titel= "【系统通知】采购信息 - 流程单审批通过通知";
            msg =  "<div><p >" + "尊敬的" + user.getLoginName() + "：</p></div>" +
                    "<div><p style='text-indent: 2em'>您好，您提交的采购信息审批已通过：</p></div>"+
                    "<div><p style='text-indent: 2em'>事项编号："+approval.getApprovalCode()+"</p></div>"+
                    "<div><p style='text-indent: 2em'>采购名称："+purchaseOrder.getPurchaseTopic()+"</p></div>"+
                    "<div><p style='text-indent: 2em'>采购单号："+purchaseOrder.getPurchaseNo()+"</p></div>"+
                    "<div><p style='text-indent: 2em'>付款期次：共"+purchaseOrder.getPaymentPlanPeriod()+"期</p></div>"+
                    "<div><p style='text-indent: 2em'>系统查看路径：客户关系管理系统 - 项目信息管理 - 项目信息 " +
                    "<a href='"+webSitUrl+"/?m=crm&p=projectmanage&me=projectmanageInfo'>进入</a></p></div>"+
                    "<div><p style='text-indent: 2em'>谢谢！</p></div>"+
                    "<div><p style='text-indent: 2em'>说明：该邮件为系统自动发送，请勿回复。</p></div>";
            ccUser = queryContractCC();
            approvalService.approved(null,purchaseOrder.getApprovalId());
            String transpondEmails = transpondEmailService.selectTranspondEmailStr(purchaseOrder.getApprovalId());
            if(!transpondEmails.isEmpty()){
                ccUser = ccUser + "," + transpondEmails;
            }
            SysUserEntity finalUser = user;
            String finalCcUser = ccUser;
            CompletableFuture.runAsync(() -> EmailUtils.sentMailByAddressee(finalUser.getEmail(), finalCcUser,titel,msg,token));
            CompletableFuture.runAsync(() -> NoticUtils.pushNotic(purchaseOrder.getApprovalId(),  approval.getCreateDataTime(),
                    approval.getCreator(),workState,23,todoUser,token));
        }else {
            if("商务审批".equals(processNodeNameAndCode.getResult().getName())){
                user = dictionaryService.queryMenuUserIdsByCode("finance").get(0);
                activitiVO.getCustomParams().put("finance",user.getAccount());
            }else if("财务审批".equals(processNodeNameAndCode.getResult().getName())){
                user = dictionaryService.queryMenuUserIdsByCode("afterSales").get(0);
                activitiVO.getCustomParams().put("afterSales",user.getAccount());
            }else if("售后审批".equals(processNodeNameAndCode.getResult().getName())){
                user = dictionaryService.queryMenuUserIdsByCode("chairman").get(0);
                activitiVO.getCustomParams().put("chairman",user.getAccount());
            }
            //审批通过（使用动态入参传入下一审批人）
            workFlowFeginService.approvalProcessCustomUserByBusinessId(activitiVO);
            //获取下一节点
            ResponseAPI<ActivitiVO> nextProcessNodeNameAndCode = workFlowFeginService.getProcessNodeNameAndCode(activitiVO);
            if(nextProcessNodeNameAndCode.getResult().getAssignee().equals(processNodeNameAndCode.getResult().getAssignee())){
                this.approvePurchaseOrderInfo(purchaseOrder,token,true);
            }else {
                workState = 0;
                //交由下一审批人处理
                todoUser = user.getUserId();
//                titel= "【系统通知】采购信息 - 流程单审批通知";
//                msg = "<div><p >" + "尊敬的" + user.getLoginName() + "：</p></div>" +
//                        "<div><p style='text-indent: 2em'>您好，您有一张新的采购信息审批需要处理：</p></div>"+
//                        "<div><p style='text-indent: 2em'>事项编号："+approval.getApprovalCode()+"</p></div>"+
//                        "<div><p style='text-indent: 2em'>申请人："+askUser.getLoginName()+ " / " + askUser.getAccount() +"</p></div>"+
//                        "<div><p style='text-indent: 2em'>申请原因："+ (StringUtils.isEmpty(purchaseOrder.getAskReason()) ? "无":purchaseOrder.getAskReason())+"</p></div>"+
//                        "<div><p style='text-indent: 2em'>申请时间："+ DateUtils.getCurrentTime() +"</p></div>"+
//                        "<div><p style='text-indent: 2em'>采购名称："+purchaseOrder.getPurchaseTopic()+"</p></div>"+
//                        "<div><p style='text-indent: 2em'>采购单号："+purchaseOrder.getPurchaseNo()+"</p></div>"+
//                        "<div><p style='text-indent: 2em'>付款期次：共"+purchaseOrder.getPaymentPlanPeriod()+"期</p></div>"+
//                        "<div><p style='text-indent: 2em'>系统审批路径：客户关系管理系统 - 待办事项 - 待办审批 " +
//                        "<a href='"+webSitUrl+"/?m=crm&p=crmtodoItems&me=todoApprovalPath>进入</a></p></div>"+
//                        "<div><p style='text-indent: 2em'>谢谢！</p></div>"+
//                        "<div><p style='text-indent: 2em'>说明：该邮件为系统自动发送，请勿回复。</p></div>";
//                String finalCcUser = ccUser;
//                SysUserEntity finalUser = user;
//                CompletableFuture.runAsync(() -> EmailUtils.sentMailByAddressee(finalUser.getEmail(), finalCcUser,titel,msg,token));
                approvalService.updateNextApproverByApprovalId(user.getUserId(),purchaseOrder.getApprovalId());
                CompletableFuture.runAsync(() -> NoticUtils.pushNotic(purchaseOrder.getApprovalId(),  approval.getCreateDataTime(),
                        approval.getCreator(),workState,23,todoUser,token));
            }
        }
        return true;
    }

    /**
     * 通过申请表主键查询现有数据
     * @param approvalId
     * @return
     */
    public PurchaseOrderVO queryPurchaseOrderByApprovalId(Integer approvalId){
        PurchaseOrderVO purchaseOrde = purchaseOrdeMapper.queryPurchaseOrderByApprovalId(approvalId);
        purchaseOrde.setForwardUsers(transpondEmailService.queryTranspondByApprovalId(approvalId));
        return purchaseOrde;
    }

    /**
     * 通过申请表主键查询历史
     * @param approvalId
     * @return
     */
    public PurchaseOrderVO queryPurchaseOrderHistoryByApprovalId(Integer approvalId){
        PurchaseOrderVO purchaseOrder = purchaseOrdeMapper.queryPurchaseOrderHistoryByApprovalId(approvalId);
        if(purchaseOrder == null){
            purchaseOrder = purchaseOrdeMapper.queryPurchaseOrderByApprovalId(approvalId);
        }
        purchaseOrder.setForwardUsers(transpondEmailService.queryTranspondByApprovalId(approvalId));
        return purchaseOrder;
    }
    @Override
    public List<PurchaseOrderVO> getPurOrdeInfoById(int purchaseOrdeId) {
        return purchaseOrdeMapper.getPurOrdeInfoById( purchaseOrdeId);
    }

    /**
     * 获取所有通过审批的采购单
     * @return
     */
    @Override
    public List<PurchaseOrderVO> getPurchaseById(Integer contractId) {
        return purchaseOrdeMapper.getPurchaseById(contractId);
    }

    @Override
    public List<PurchaseOrderVO> getWmsProjectInfo(Integer contractId) {
        return purchaseOrdeMapper.getWmsProjectInfo(contractId);
    }


    @Override
    public List<BillingApplyDto> getAllContract(Integer projectManageId) {
        return purchaseOrdeMapper.getAllContract(projectManageId);
    }

    /**
     * 开启审批流程
     * @param
     * @param user
     * @return
     */
    private Integer startPurchaseOrdeApproval(SysUserEntity user){
        ActivitiVO activitiVO = new ActivitiVO();
        activitiVO.setAuthorization(AuthUtils.getUserAccount());
        activitiVO.setProcessName("采购审批");
        activitiVO.setProcessCode("purchaseOrde_approval");
        activitiVO.setNextNodeParams("commercialSpecialist");
//        HashMap<String,Object> customParams = new HashMap<>();
        //商务负责人
        SysUserEntity business = dictionaryService.queryMenuUserIdsByCode("commercialSpecialist").get(0);
        activitiVO.setNextNodeAssignee(business.getAccount());
//        customParams.put("commercialSpecialist",business.getAccount());
//        //财务负责人
//        SysUserEntity finance = dictionaryService.queryMenuUserIdsByCode("finance").get(0);
//        customParams.put("finance",finance.getAccount());
//        //售后负责人
//        SysUserEntity afterSales = dictionaryService.queryMenuUserIdsByCode("afterSales").get(0);
//        customParams.put("afterSales",afterSales.getAccount());
//        //总经理
//        SysUserEntity president = dictionaryService.queryMenuUserIdsByCode("president").get(0);
//        customParams.put("president",president.getAccount());
//        //董事长
//        SysUserEntity chairman = dictionaryService.queryMenuUserIdsByCode("chairman").get(0);
//        customParams.put("chairman",chairman.getAccount());
//        activitiVO.setCustomParams(customParams);
        ResponseAPI<ActivitiVO> responseAPI = workFlowFeginService.startMaxVersionProcessByDesignCodeCustomParams(activitiVO);
        return responseAPI.getResult().getBusinessId();
    }

    /**
     * 生成邮件内推
     * @param userName 邮件通知人
     * @param msgTopic 邮件主题
     * @param approvalCode 事项编号
     * @param askeUserName 申请人
     * @param purchaseOrdeTopic 采购名称
     * @param purchaseOrdeNo 采购单号
     * @param bmpPeriod 付款期次
     * @return
     */
    private String initPurchaseOrdeEmailData(String userName,String msgTopic,String approvalCode,String askeUserName,
                                         String purchaseOrdeTopic, String purchaseOrdeNo,Integer bmpPeriod){
        String msg =  "<div><p >" + "尊敬的" + userName + "：</p></div>" +
                "<div><p style='text-indent: 2em'>您好，"+msgTopic +"：</p></div>"+
                "<div><p style='text-indent: 2em'>事项编号："+approvalCode+"</p></div>"+
                "<div><p style='text-indent: 2em'>申请人："+askeUserName+"</p></div>"+
                "<div><p style='text-indent: 2em'>采购名称："+purchaseOrdeTopic+"</p></div>"+
                "<div><p style='text-indent: 2em'>合同单号："+purchaseOrdeNo+"</p></div>"+
                "<div><p style='text-indent: 2em'>付款期次：共"+bmpPeriod+"期</p></div>";
        if(msgTopic.contains("处理")){
            msg += "<div><p style='text-indent: 2em'>系统审批路径：客户关系管理系统 - 待办事项 - 待办审批 " +
                    "<a href='"+webSitUrl+"/?m=crm&p=crmtodoItems&me=todoApprovalPath'>进入</a></p></div>"+
                    "<div><p style='text-indent: 2em'>谢谢！</p></div>"+
                    "<div><p style='text-indent: 2em'>说明：该邮件为系统自动发送，请勿回复。</p></div>";
        }else {
            msg += "<div><p style='text-indent: 2em'>谢谢！</p></div>"+
                    "<div><p style='text-indent: 2em'>说明：该邮件为系统自动发送，请勿回复。</p></div>";
        }
        return msg;
    }

    /**
     * 获取采购抄送人
     * @return
     */
    private String queryContractCC(){
        //获取抄送人
        List<SysUserEntity> userIds = dictionaryService.queryCcUserIdsByCode("purchaseCC");
        StringBuilder emailList = new StringBuilder();
        for (int i = 0; i < userIds.size(); i++) {
            if (userIds.size()-1 == i){
                emailList.append(userIds.get(i).getEmail());
            }else {
                emailList.append(userIds.get(i).getEmail());
                emailList.append(",");
            }
        }
        return emailList.toString();
    }

    /**
     * 分页查询
     *
     * @param page
     * @param entity
     * @return
     */
    public PageUtil<PurchaseOrderVO> queryPurchaseOrdesByPage(IPage page, PurchaseOrderVO entity, String token){
        List<SysUserEntity> userList = this.queryUserList(AuthUtils.getUserId(),"purchaseOrde", token);
        IPage<PurchaseOrderVO> iPage = purchaseOrdeMapper.queryPurchaseOrdesByPage(page, entity,userList);
        List<PurchaseOrderVO> list = iPage.getRecords();
        if(!list.isEmpty()){
            BigDecimal totlePricePage = new BigDecimal(0);
            BigDecimal paymentMoneyPage = new BigDecimal(0);
            BigDecimal tickerMoneyPage = new BigDecimal(0);
            BigDecimal refundMoneyPage = new BigDecimal(0);
            for (PurchaseOrderVO pVo: list) {
                if(pVo.getTotlePrice()!= null){
                    totlePricePage = totlePricePage.add( new BigDecimal(pVo.getTotlePrice()));
                }
                if(pVo.getPaymentMoneys() != null) {
                    paymentMoneyPage = paymentMoneyPage.add(pVo.getPaymentMoneys());
                }
                if(pVo.getTickerMoneys() != null) {
                    tickerMoneyPage = tickerMoneyPage.add(pVo.getTickerMoneys());
                }
                if (pVo.getRefundMoney() != null) {
                    refundMoneyPage = refundMoneyPage.add(pVo.getRefundMoney());
                }
            }
            list.get(0).setTotlePricePage(String.valueOf(totlePricePage));
            list.get(0).setPaymentMoneyPage(String.valueOf(paymentMoneyPage));
            list.get(0).setTickerMoneyPage(String.valueOf(tickerMoneyPage));
            list.get(0).setRefundMoneyPage(String.valueOf(refundMoneyPage));
            iPage.setRecords(list);
        }
        return new PageUtil(iPage);
    }

    /**
     * 分页查询待办信息
     *
     * @param page
     * @param entity
     * @return
     */
    public PageUtil<PurchaseOrderVO> queryApprovalPurByPage(IPage page, PurchaseOrderVO entity){
        //获取工作流待办
        ActivitiVO activitiVO = new ActivitiVO();
        activitiVO.setAuthorization(AuthUtils.getUserAccount());
        ResponseAPI<List<ActivitiVO>> workFlowVoResponseAPI = workFlowFeginService.getTasksByAuthorization(activitiVO);
        List<ActivitiVO> activitiVOS = workFlowVoResponseAPI.getResult();
        if( activitiVOS == null || activitiVOS.size() == 0 ){
            return new PageUtil(new PageDTO());
        }else{
            return new   PageUtil(purchaseOrdeMapper.queryApprovalPurByPage(page, entity,activitiVOS));
        }
    }

    /**
     * 分页查询已办信息
     *
     * @param page
     * @param entity
     * @return
     */
    public PageUtil<PurchaseOrderVO> queryApprovalPurDoneByPage(IPage page, PurchaseOrderVO entity){
        IPage<PurchaseOrderVO> iPage = purchaseOrdeMapper.queryApprovalPurDoneByPage(page, entity);
        return new PageUtil(iPage);
    }


    /**
     * 分页查询申请记录信息
     *
     * @param page
     * @param entity
     * @return
     */
    public PageUtil<PurchaseOrderVO> queryApprovalPurRecordByPage(IPage page, PurchaseOrderVO entity,String token){
        List<SysUserEntity> userList = this.queryUserList(AuthUtils.getUserId(),"approvalRecord", token);
        IPage<PurchaseOrderVO> iPage = purchaseOrdeMapper.queryApprovalPurRecordByPage(page, entity,userList);
        return new PageUtil(iPage);
    }

    /**
     * 一指禅系统产品列表导出
     *
     * @param response
     */
    public void exportPurchaseOrdes(HttpServletResponse response, PurchaseOrderVO entit, String token) throws Exception{
        List<SysUserEntity> userList = this.queryUserList(AuthUtils.getUserId(),"purchaseOrde", token);
        List<PurchaseOrderVO> purchaseOrdes = purchaseOrdeMapper.queryPurchaseOrdes(entit,userList);
        List<String> codes = new ArrayList<>();
        codes.add("paymentPlanPeriod");
        codes.add("purchaseType");
        Map<String, List<DictionaryLookupItemVO>> stringListMap = dictionaryService.queryDictionaryLookupInfo(null, codes);
        for (int i = 0; i < purchaseOrdes.size(); i++) {
            PurchaseOrderVO purchaseOrder = purchaseOrdes.get(i);
            //付款期次
            for(DictionaryLookupItemVO dictionaryLookupItemVO : stringListMap.get("paymentPlanPeriod") ){
                if(dictionaryLookupItemVO.getItemCode().equals(purchaseOrder.getPaymentPlanPeriod()+"")){
                    purchaseOrder.setPaymentPlanPeriodStr(dictionaryLookupItemVO.getItemName());
                    break;
                }
            }
            //采购类型
            for(DictionaryLookupItemVO dictionaryLookupItemVO : stringListMap.get("purchaseType") ){
                if(dictionaryLookupItemVO.getItemCode().equals(purchaseOrder.getPurchaseType()+"")){
                    purchaseOrder.setPurchaseTypeStr(dictionaryLookupItemVO.getItemName());
                    break;
                }
            }

            if(Integer.valueOf(0).equals(purchaseOrder.getPurchaseCategories())){
                purchaseOrder.setPurchaseCategoriesStr("机会采购");
                purchaseOrder.setProjectManageTheme(purchaseOrder.getOpportunityTheme());
            }else {
                purchaseOrder.setPurchaseCategoriesStr("项目采购");
            }


            if(0 == purchaseOrder.getApproval().getApprovalStatus()){
                purchaseOrder.setApprovalStr("审批中");
            }else if(1 == purchaseOrder.getApproval().getApprovalStatus()){
                purchaseOrder.setApprovalStr("已通过");
            }else if(2 == purchaseOrder.getApproval().getApprovalStatus()){
                purchaseOrder.setApprovalStr("已驳回");
            }else if(3 == purchaseOrder.getApproval().getApprovalStatus()){
                purchaseOrder.setApprovalStr("已撤回");
            }else if(5 == purchaseOrder.getApproval().getApprovalStatus()){
                purchaseOrder.setApprovalStr("撤回中");
            }
            purchaseOrder.setPurchaseDateStr(String.format("%tY-%<tm-%<td",purchaseOrder.getPurchaseDate()));
        }

        //获取yml模板位置
        YamlPropertiesFactoryBean factoryBean = new YamlPropertiesFactoryBean();
        String path = "application.yml";
        factoryBean.setResources(new ClassPathResource(path));
        Properties properties = factoryBean.getObject();
        String contractTemplatePath = String.valueOf(properties.get("report.purchaseTemplate"));

        //依据根目录获取模板位置
        TemplateExportParams params = new TemplateExportParams(contractTemplatePath);
        Map<String, Object> map = new HashMap<>();
        map.put("purchaseInfos",purchaseOrdes);
        ReportUtils.exportExcel(params,map,"采购列表",response);
    }

    public List<SysUserEntity> queryUserList(Integer userId,String authCode, String token) {
        List<SysUserEntity> userList = new ArrayList<>();
        List<SysUserEntity> authUserIList = dictionaryService.queryAuthUserIdsByCode(authCode);
        boolean result = false;
        for (SysUserEntity user:authUserIList) {
            if (Objects.equals(user.getUserId(), userId)) {
                result = true;
            }
        }
        if (result) {
            userList = feginService.getUserIgnoreFlag(token).getResult();
        } else {
            SysUserEntity user = feginService.searchUserInfoByIds(userId,token).getResult();
            if (user.getIsLeader() == 1) {
                userList = feginService.recursiveQueryAllUserByLeaderId(userId, token).getResult();
            }
            userList.add(user);
        }
        return userList;
    }

    /**
     * 分页查询
     *
     * @param page
     * @param entity
     * @return
     */
    public PageUtil<PurchaseOrderProductVO> queryPurchaseProductsByPage(IPage page, PurchaseOrderProductVO entity, String token){
        List<SysUserEntity> userList = this.queryUserList(AuthUtils.getUserId(),"purchaseOrde", token);
        IPage<PurchaseOrderProductVO>  iPage = purchaseOrdeMapper.queryPurchaseProductsByPage(page, entity, userList);
        List<PurchaseOrderProductVO> list = iPage.getRecords();
        if(!list.isEmpty()) {
            BigDecimal purchaseProductTotalPricePage = new BigDecimal(0);
            for (PurchaseOrderProductVO poVo : list) {
                if (poVo.getPurchaseProductTotalPrice() != null) {
                    purchaseProductTotalPricePage = purchaseProductTotalPricePage.add(poVo.getPurchaseProductTotalPrice());
                }
            }
            list.get(0).setPurchaseProductTotalPricePage(String.valueOf(purchaseProductTotalPricePage));
            iPage.setRecords(list);
        }
        return new PageUtil(iPage);
    }

    /**
     * 更据采购ID获取采购相关付款 收票记录
     * @param purId
     * @return
     */
    public Map<String, BigDecimal> queryPurPayInfoByPurId(Integer purId){
        MapResultHandler<String, BigDecimal> resultHandler = new MapResultHandler<>();
        purchaseOrdeMapper.queryPurPayInfoByPurId(resultHandler,purId);
        Map<String, BigDecimal> results = resultHandler.getMappedResults();
        //采购未付款金额 采购总金额-已付款金额
        results.put("未付款总金额", results.get("采购总金额").subtract(results.get("付款总金额")).setScale(2, RoundingMode.HALF_DOWN));
        return results;
    }


    /**
     * 更据项目ID获取采购相关付款 收票记录
     * @param proId
     * @return
     */
    public Map<String, BigDecimal> queryPurPayInfoByProId(Integer proId){
        MapResultHandler<String, BigDecimal> resultHandler = new MapResultHandler<>();
        purchaseOrdeMapper.queryPurPayInfoByProId(resultHandler,proId);
        SalesProjectManageVO project = projectManageMapper.selectProjectManageMoneyById(proId);
        Map<String, BigDecimal> results = resultHandler.getMappedResults();
        //采购未付款金额 采购总金额-已付款金额
        //results.put("未付款总金额", results.get("项目金额").subtract(results.get("付款总金额")).setScale(2, RoundingMode.HALF_DOWN));
        results.put("已收票金额",results.get("收票总金额").compareTo(BigDecimal.ZERO) >= 0 ? results.get("收票总金额") : BigDecimal.ZERO);
            results.put("考核利润",new BigDecimal(project.getProjectManageMoney().getValue()));
        results.put("未付款",results.get("采购总金额").subtract(results.get("付款总金额")));
        results.put("实时利润",results.get("回款总金额").add(results.get("已退款")).subtract(results.get("已报销")).subtract(results.get("付款总金额")).subtract(results.get("人天服务")).subtract(results.get("质保服务")));
        return results;
    }


    @Resource
    private SalesProjectManageMapper salesProjectManageMapper;

    @Resource
    private SalesOpportunityMapper salesOpportunityMapper;

    @Resource
    private ReimburseService reimburseService;
    /**
     * 根据客户ID获取数据总和
     * @param customerId
     * @return
     */
    public Map<String, BigDecimal> queryPurPayInfoByCustomerId(Integer customerId,String token){
        MapResultHandler<String, BigDecimal> resultHandler = new MapResultHandler<>();
        purchaseOrdeMapper.queryPurPayInfoByCustomerId(resultHandler,customerId);
        Map<String, BigDecimal> results = resultHandler.getMappedResults();

        results.put("未回款金额",results.get("合同单总额").subtract(results.get("已回款金额")));

        // 获取项目相关信息
        List<SalesProjectManageVO> salesProjectManageVOS = salesProjectManageMapper.queryProjectByCustomerId(customerId);

        // 获取机会信息
        List<SalesOpportunityVO> salesOpportunityVOS = salesOpportunityMapper.queryOpportunityByCustomerId(customerId);
        // 整理当前客户名下所有的机会ID以及项目ID；
        FeeMainVO feeMainVO = new FeeMainVO();
        if (salesProjectManageVOS != null && salesProjectManageVOS.size() > 0){
            List<Integer> projectIdList = new ArrayList<>();
            for (SalesProjectManageVO item : salesProjectManageVOS) {
                projectIdList.add(item.getProjectManageId());
            }
            feeMainVO.setProjectIdList(projectIdList);
        }
        if (salesOpportunityVOS != null && salesOpportunityVOS.size() > 0){
            List<Integer> opportunityIdList = new ArrayList<>();
            for (SalesOpportunityVO item : salesOpportunityVOS) {
                opportunityIdList.add(item.getOpportunityId());
            }
            feeMainVO.setChanceIdList(opportunityIdList);
        }
        BigDecimal sum = BigDecimal.ZERO;
        //获取报销信息
        if ((feeMainVO.getProjectIdList() != null && feeMainVO.getProjectIdList().size() > 0) || (feeMainVO.getChanceIdList() != null && feeMainVO.getChanceIdList().size() > 0)){
            List<LinkedHashMap> resultList = (List<LinkedHashMap>) reimburseService.queryReimburseListByProjectIdListOrChanceIdList(feeMainVO,token).getResult();
            if (resultList != null && resultList.size() > 0){
            for (LinkedHashMap result : resultList) {

                // 从 LinkedHashMap 中提取属性
                String reimburseMoney = result.get("reimburseMoney").toString();
                String substring = reimburseMoney.substring("{value=".length(), reimburseMoney.length() - 1);
                // 检查属性是否存在，以及类型是否匹配
                if (substring != null) {
                    BigDecimal reimburseMoney1 = new BigDecimal(substring);
                    sum = sum.add(reimburseMoney1);
                }
            }
            }
        }
        results.put("费用报销",sum);

        return results;
    }

    /**
     * 根据供应商ID获取数据总和
     * @param supplierId
     * @return
     */
    public Map<String, BigDecimal> queryPurPayInfoBySupplierId(Integer supplierId,String token){
        MapResultHandler<String, BigDecimal> resultHandler = new MapResultHandler<>();
        purchaseOrdeMapper.queryPurPayInfoBySupplierId(resultHandler,supplierId);
        Map<String, BigDecimal> results = resultHandler.getMappedResults();

        results.put("未付款金额",results.get("采购总金额").subtract(results.get("已付款金额")));

        return results;
    }

    /**
     * 导出采购明细数据
     *
     * @param response
     */
    public void exportPurchaseProducts(HttpServletResponse response, PurchaseOrderProductVO entit, String token) throws Exception{
        List<SysUserEntity> userList = this.queryUserList(AuthUtils.getUserId(),"purchaseOrde", token);
        List<PurchaseOrderProductVO> purchaseOrderProducts = purchaseOrdeMapper.queryPurchaseProducts(entit,userList);
        List<String> codes = new ArrayList<>();
        codes.add("productType");
        Map<String, List<DictionaryLookupItemVO>> stringListMap = dictionaryService.queryDictionaryLookupInfo(null, codes);
        for (int i = 0; i < purchaseOrderProducts.size(); i++) {
            PurchaseOrderProductVO purchaseOrderProductVO = purchaseOrderProducts.get(i);
            PurchaseOrderVO purchaseOrder = purchaseOrderProductVO.getPurchaseOrder();
            //付款期次
            for(DictionaryLookupItemVO dictionaryLookupItemVO : stringListMap.get("productType") ){
                if(dictionaryLookupItemVO.getItemCode().equals(purchaseOrderProductVO.getProductInfo().getProductCategory()+"")){
                    purchaseOrderProductVO.getProductInfo().setProductCategoryStr(dictionaryLookupItemVO.getItemName());
                    break;
                }
            }
            if(Integer.valueOf(0).equals(purchaseOrder.getPurchaseCategories())){
                purchaseOrder.setPurchaseCategoriesStr("机会采购");
                purchaseOrder.setProjectManageTheme(purchaseOrder.getOpportunityTheme());
            }else {
                purchaseOrder.setPurchaseCategoriesStr("项目采购");
            }

            purchaseOrder.setPurchaseDateStr(String.format("%tY-%<tm-%<td",purchaseOrder.getPurchaseDate()));
        }

        //获取yml模板位置
        YamlPropertiesFactoryBean factoryBean = new YamlPropertiesFactoryBean();
        String path = "application.yml";
        factoryBean.setResources(new ClassPathResource(path));
        Properties properties = factoryBean.getObject();
        String contractTemplatePath = String.valueOf(properties.get("report.purchaseProductsTemplate"));

        //依据根目录获取模板位置
        TemplateExportParams params = new TemplateExportParams(contractTemplatePath);
        Map<String, Object> map = new HashMap<>();
        map.put("purchaseProductInfos",purchaseOrderProducts);
        ReportUtils.exportExcel(params,map,"采购明细列表",response);
    }

    public Boolean deletePurchaseOrderById(Integer purchaseOrdeId){
        return purchaseOrdeMapper.deletePurchaseOrderById(purchaseOrdeId);
    }

    @Override
    public void updatePurchaseOrdeAfterPass(PurchaseOrderVO purchaseOrderVO, String token) {
        // 将修改后的数据放入redis缓存
        Map<String,Object> projectInfoMap = new HashMap<>();
        projectInfoMap.put(purchaseOrderVO.getPurchaseId().toString(),purchaseOrderVO);
        feginService.setCacheInfo(Constants.CACHE_PURCHASEORDER + purchaseOrderVO.getPurchaseId(),projectInfoMap,token);
    }

    @Override
    public PurchaseOrderVO queryPurchaseOrdeFromCache(int purchaseId, String token) {
        String managerCacheKey = Constants.CACHE_PURCHASEORDER+purchaseId;
        ResponseAPI cacheInfo = feginService.getCacheInfo(managerCacheKey,String.valueOf(purchaseId), token);
        String jsonObject= JSON.toJSONString(cacheInfo.getResult());
        //将json转成需要的对象
        PurchaseOrderVO purchaseOrderVO = JSONObject.parseObject(jsonObject,PurchaseOrderVO.class);
        return purchaseOrderVO;
    }

    @Override
    public PageUtil<PurchaseOrderVO> queryRefundDetailsByPage(IPage page, PurchaseOrderVO entity) {
        IPage<PurchaseOrderVO> iPage = purchaseOrdeMapper.queryRefundDetailsByPage(page, entity);
        List<PurchaseOrderVO> list = iPage.getRecords();
        if(!list.isEmpty()){
            this.getRefundDetailInfo(list);
            iPage.setRecords(list);
        }
        return new PageUtil(iPage);
    }

    @Override
    public Map<String, String> queryRefundCharData() {
        List<Map<String,Object>> list = purchaseOrdeMapper.queryRefundCharData();
        BigDecimal bidBondTotlePrice = new BigDecimal(0);
        BigDecimal bidBondRefundMoney = new BigDecimal(0);
        BigDecimal performanceBondsTotlePrice = new BigDecimal(0);
        BigDecimal performanceBondsRefundMoney = new BigDecimal(0);
        for (Map<String, Object> item : list) {
            if ("bidBond".equals(item.get("type"))) {
                bidBondTotlePrice = bidBondTotlePrice.add(new BigDecimal(item.get("totlePrice").toString()));
                bidBondRefundMoney = bidBondRefundMoney.add(new BigDecimal(item.get("refundMoney").toString()));
            } else if ("performanceBonds".equals(item.get("type"))) {
                performanceBondsTotlePrice = performanceBondsTotlePrice.add(new BigDecimal(item.get("totlePrice").toString()));
                performanceBondsRefundMoney = performanceBondsRefundMoney.add(new BigDecimal(item.get("refundMoney").toString()));
            }
        }
        Map<String, String> map = new HashMap();
        BigDecimal bigDecimal = new BigDecimal("10000");
        map.put("bidBondTotlePrice",  bidBondTotlePrice.divide(bigDecimal).setScale(2, BigDecimal.ROUND_HALF_UP).stripTrailingZeros().toPlainString());
        map.put("bidBondRefundMoney", bidBondRefundMoney.divide(bigDecimal).setScale(2, BigDecimal.ROUND_HALF_UP).stripTrailingZeros().toPlainString());
        map.put("noBidBondRefundMoney", bidBondTotlePrice.subtract(bidBondRefundMoney).divide(bigDecimal).setScale(2, BigDecimal.ROUND_HALF_UP).stripTrailingZeros().toPlainString());
        map.put("performanceBondsTotlePrice", performanceBondsTotlePrice.divide(bigDecimal).setScale(2, BigDecimal.ROUND_HALF_UP).stripTrailingZeros().toPlainString());
        map.put("performanceBondsRefundMoney", performanceBondsRefundMoney.divide(bigDecimal).setScale(2, BigDecimal.ROUND_HALF_UP).stripTrailingZeros().toPlainString());
        map.put("noPerformanceBondsRefundMoney", performanceBondsTotlePrice.subtract(performanceBondsRefundMoney).divide(bigDecimal).setScale(2, BigDecimal.ROUND_HALF_UP).stripTrailingZeros().toPlainString());
        return new HashMap<>(map);
    }

    @Override
    public void exportRefundDetails(HttpServletResponse response, PurchaseOrderVO entity) throws Exception {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        List<PurchaseOrderVO> list = purchaseOrdeMapper.queryRefundDetails(entity);
        if (!CollUtil.isEmpty(list)) {
            this.getRefundDetailInfo(list);
        }

        // 新增一行，处理合计问题
        PurchaseOrderVO vo = new PurchaseOrderVO();
        if (!CollUtil.isEmpty(list)) {
            vo.setTotlePrice(list.get(0).getTotlePricePage());
            vo.setPaymentMoneys(new BigDecimal(list.get(0).getPaymentMoneyPage()));
            vo.setRefundMoney(new BigDecimal(list.get(0).getRefundMoneyPage()));
            vo.setUnrefundedMoney(new BigDecimal(list.get(0).getUnrefundedMoneyPage()));
            vo.setPurchaseNo("合计");
            list.add(vo);
        }
        List<Map<String,Object>> tableConfigList = purchaseOrdeMapper.queryRefundShowTableConfig("pms", "refundDetails");
        List<Map<String,String>> refundStatus = purchaseOrdeMapper.queryRefundStatus();
        List<Map<String,String>> refundType = purchaseOrdeMapper.queryRefundType();
        Map<String,String> refundStatusMap = new HashMap<>();
        Map<String,String> refundTypeMap = new HashMap<>();
        for (Map<String, String> item : refundStatus) {
            refundStatusMap.put(item.get("code"), item.get("name"));
        }
        for (Map<String, String> item : refundType) {
            refundTypeMap.put(item.get("code"), item.get("name"));
        }
        LinkedHashMap<String, DynamicExcelData> nameMap = new LinkedHashMap<>(0,1.6f,true);
        for (Map item : tableConfigList) {
            String str = String.valueOf(item.get("prop"));
            if (!"refundProgress".equals(str)) {
                if ("header".equals(str)) {  // 人员名称特殊处理，字段替换
                    str = "userName";
                }
                nameMap.put(str, new DynamicExcelData(String.valueOf(item.get("label")), "0"));
            }
        }

        List<Map<String, Object>> dataList = getDataList(list, Arrays.asList());
        dynamicExport(response,nameMap, dataList,"退款详情", null, false, null);
    }

    private void getRefundDetailInfo(List<PurchaseOrderVO> list) {
        BigDecimal totlePricePage = new BigDecimal(0);
        BigDecimal paymentMoneyPage = new BigDecimal(0);
        BigDecimal tickerMoneyPage = new BigDecimal(0);
        BigDecimal refundMoneyPage = new BigDecimal(0);
        BigDecimal unrefundedMoneyPage = new BigDecimal(0);
        BigDecimal initMoney = new BigDecimal("0.00");
        for (PurchaseOrderVO pVo: list) {
            if(pVo.getTotlePrice()!= null){
                totlePricePage = totlePricePage.add( new BigDecimal(pVo.getTotlePrice()));
            }
            if(pVo.getPaymentMoneys() != null) {
                paymentMoneyPage = paymentMoneyPage.add(pVo.getPaymentMoneys());
            }
            if(pVo.getTickerMoneys() != null) {
                tickerMoneyPage = tickerMoneyPage.add(pVo.getTickerMoneys());
            }
            if (pVo.getRefundMoney() != null) {
                refundMoneyPage = refundMoneyPage.add(pVo.getRefundMoney());
            }
            pVo.setUnrefundedMoney((!Objects.isNull(pVo.getPaymentMoneys()) ? pVo.getPaymentMoneys() : initMoney).subtract(Objects.isNull(pVo.getRefundMoney()) ? initMoney : pVo.getRefundMoney()));

            unrefundedMoneyPage = unrefundedMoneyPage.add(pVo.getUnrefundedMoney());

            // 计算逾期天数，采购金额等于已退金额时不存在逾期天数
            ZoneId zoneId = ZoneId.systemDefault();
            if (pVo.getPaymentMoneys().compareTo(pVo.getRefundMoney()) == 0 && pVo.getRefundMoney().compareTo(BigDecimal.ZERO) > 0) {
                Instant actualRefundInstant =  pVo.getActualRefundDate().toInstant();
                LocalDate actualRefund = actualRefundInstant.atZone(zoneId).toLocalDate();
                if (!Objects.isNull(pVo.getRefundDate())) {
                    Instant refundDateInstant = pVo.getRefundDate().toInstant();
                    LocalDate refundDate = refundDateInstant.atZone(zoneId).toLocalDate();
                    long daysOverdue = ChronoUnit.DAYS.between(refundDate, actualRefund);
                    pVo.setOverdueDays(String.valueOf(daysOverdue));
                }
                pVo.setCurrentStatus("3"); // 已退款
            } else {
                LocalDate currentDate = LocalDate.now();
                if (!Objects.isNull(pVo.getRefundDate())) {
                    Instant refundDateInstant = pVo.getRefundDate().toInstant();
                    LocalDate refundDate = refundDateInstant.atZone(zoneId).toLocalDate();
                    if (refundDate.isAfter(currentDate) || refundDate.isEqual(currentDate)) {  // 计划回款日期小于等于当前日期
                        if (!Objects.isNull(pVo.getActualRefundDate())) {  // 实际回款日期为空时，以当前系统时间为准计算逾期天数
                            Instant actualRefundInstant =  pVo.getActualRefundDate().toInstant();
                            LocalDate actualRefund = actualRefundInstant.atZone(zoneId).toLocalDate();
                            long daysOverdue = ChronoUnit.DAYS.between(refundDate, actualRefund); // 未到期计算计划回款日期与当前系统时间差值
                            pVo.setOverdueDays(String.valueOf(daysOverdue));
                        } else {
                            long daysOverdue = ChronoUnit.DAYS.between(refundDate, currentDate); // 未到期计算计划回款日期与时间回款日期差值
                            pVo.setOverdueDays(String.valueOf(daysOverdue));
                        }
                        pVo.setCurrentStatus("1"); // 未到期
                    } else {
                        long daysOverdue = ChronoUnit.DAYS.between(refundDate, currentDate); // 逾期：计算计划回款日期与当前时间差值
                        pVo.setOverdueDays(String.valueOf(daysOverdue));
                        pVo.setCurrentStatus("2"); // 已逾期
                    }
                } else {
                    pVo.setCurrentStatus("0"); // 没有计划退款时间
                }
            }
        }
        list.get(0).setTotlePricePage(String.valueOf(totlePricePage));
        list.get(0).setPaymentMoneyPage(String.valueOf(paymentMoneyPage));
        list.get(0).setTickerMoneyPage(String.valueOf(tickerMoneyPage));
        list.get(0).setRefundMoneyPage(String.valueOf(refundMoneyPage));
        list.get(0).setUnrefundedMoneyPage(String.valueOf(unrefundedMoneyPage));
    }

    @Override
    public List<PurchaseOrderVO> selectAllProjectByPur(){
        return purchaseOrdeMapper.selectAllProjectByPur();
    }

    @Override
    public List<PurchaseOrderVO> selectAllProjectByPurCreate(String token){
        List<SysUserEntity> userList = this.queryUserList(AuthUtils.getUserId(),Constants.OPPORTUNITY_MODEL_NAME, token);
        return purchaseOrdeMapper.selectAllProjectByPurCreate(userList);
    }
}
